package br.com.esporte.view.site.grupo.comunidade.partida;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import br.com.base.exception.NegociosException;
import br.com.esporte.exception.ViewException;
import br.com.esporte.model.Advertencia;
import br.com.esporte.model.DiaPraticadoGrupo;
import br.com.esporte.model.EntidadeEsporte;
import br.com.esporte.model.Grupo;
import br.com.esporte.model.Jogador;
import br.com.esporte.model.Partida;
import br.com.esporte.model.Time;
import br.com.esporte.model.Usuario;
import br.com.esporte.model.VersusEnum;
import br.com.esporte.persistence.filter.FiltroAdvertencia;
import br.com.esporte.persistence.filter.FiltroJogador;
import br.com.esporte.view.infra.generic.IPaginaCadastro;
import br.com.esporte.view.infra.generic.Pagina;
import br.com.esporte.view.infra.generic.PaginaModalComponent;
import br.com.esporte.view.infra.html.JavaScriptParam;
import br.com.esporte.view.site.component.menu.menuTopo.MenuTopo;
import br.com.esporte.view.site.component.menu.menuTopo.MenuTopoComponente;
import br.com.esporte.view.site.component.time.TimeComponent;
import br.com.esporte.view.site.grupo.comunidade.PaginaComunidade;
import br.com.esporte.view.site.grupo.comunidade.diaPraticado.PaginaListarDiaPraticado;

/**
 * 
 * @author Milton Domingues
 *
 */
public class PaginaCriarPartida extends PaginaComunidade implements IPaginaCadastro, PaginaModalComponent{

	private DiaPraticadoGrupo diaPraticadoGrupo;

	private static final String FORM = "form";
	private static final String TIME_1_ID = "time1";
	private static final String TIME_2_ID = "time2";
	private static final String VERSUS_ID = "versus";
	private static final String MODAL_ID = "modal";
	private static final String PLACAR_AZUL = "placarAzul";
	private static final String PLACAR_VERMELHO = "placarVermelho";
	private static final String BOTAO_SALVAR = "btSalvar";
	private static final String LIST_MENUS_TOPO_ID = "menuTopo";
	private VersusEnum versus;
	private Partida partida;
	private List<Jogador> jogadoresTime1;
	private List<Jogador> jogadoresTime2;
	private int placarTime1;

	private int placarTime2;

	public PaginaCriarPartida(Grupo grupo, DiaPraticadoGrupo diaPraticadoGrupo) {
		super(grupo);
		setDiaPraticadoGrupo(diaPraticadoGrupo);
	}

	public PaginaCriarPartida(Grupo grupo, Partida partida){
		setGrupo(grupo);
		setPartida(partida);
		setDiaPraticadoGrupo(partida.getDiaPraticado());
		montarPagina();
	}

	@Override
	public void acaoModal(AjaxRequestTarget target) {

	}

	@Override
	public void acaoModal(EntidadeEsporte entidade, AjaxRequestTarget target) {

	}

	@Override
	public void acaoModal(EntidadeEsporte entidade, AjaxRequestTarget target, Component component) {
		TimeComponent time = (TimeComponent) component;

		ModalWindow modal =	(ModalWindow) getContainer().get(MODAL_ID);
		ModalJogador modalJogador = (ModalJogador) modal.get(modal.getContentId());
		modalJogador.setTime(component);

		// seleciona qual placar enviar para o modal
		if(time.getId().equals(TIME_1_ID)){
			modalJogador.setPlacar(getContainer().get(FORM).get(PLACAR_VERMELHO));
		}else{
			modalJogador.setPlacar(getContainer().get(FORM).get(PLACAR_AZUL));
		}

		// limpa modal
		modalJogador.limpar(target);

		// seta valores base para o modal
		modalJogador.setJogadores(time.getJogadores());
		modalJogador.setJogador((Jogador) entidade);
		modalJogador.setUsuario(((Jogador) entidade).getUsuario());

		// inicia valores modal
		modalJogador.carregarView(target);

		modal.show(target);
	}

	@Override
	public void acaoSalvar() {

		partida.setVersus(getVersus());
		partida.setDiaPraticado(getDiaPraticadoGrupo());

		Time time1 = partida.getTimes().get(0);
		time1.setPartida(partida);
		time1.setJogadores(getJogadoresTime1());

		Time time2 = partida.getTimes().get(1);
		time2.setPartida(partida);
		time2.setJogadores(getJogadoresTime2());

		partida.setTimes(Arrays.asList(time1, time2));

		if(isUpdate()){
			getFachada().alterar(partida, getUsuarioLogado());
		}else{
			getFachada().inserir(partida, getUsuarioLogado());
		}
	}

	private int adicionarJogadoresTime(Time time, List<Jogador> jogadoresTime){
		int placarTime = 0;
		FiltroJogador filtroJogador1 = new FiltroJogador();
		filtroJogador1.addEquals(FiltroJogador.TIME, time);
		List<Jogador> jogadores = getFachada().consultar(filtroJogador1);
		for (Jogador jogador : jogadores) {
			jogadoresTime.add(jogador);
			jogador.setAdvertencias(consultarAdvsjogador(jogador));
			placarTime += jogador.getPonto();
		}
		return placarTime;
	}

	@Override
	public void carregarView() {
		super.carregarView();
		if(isUpdate()){
			setVersus(partida.getVersus());
			popularEdicaoJogadores(partida);
		}else{
			partida = new Partida();
			setJogadoresTime1(new ArrayList<Jogador>());
			setJogadoresTime2(new ArrayList<Jogador>());
			partida.setTimes(new ArrayList<Time>());
			Time time1 = new Time();
			time1.setPartida(partida);
			time1.setJogadores(getJogadoresTime1());
			Time time2 = new Time();
			time2.setPartida(partida);
			time1.setJogadores(getJogadoresTime2());
			partida.getTimes().add(time1);
			partida.getTimes().add(time2);
		}
	}

	private List<Advertencia> consultarAdvsjogador(Jogador jogador){
		FiltroAdvertencia filtro = new FiltroAdvertencia();
		filtro.addEquals(FiltroAdvertencia.JOGADOR, jogador);
		return getFachada().consultar(filtro);
	}

	private Button criarBtSalvar() {
		Button botao = new Button(BOTAO_SALVAR){
			private static final long serialVersionUID = -3960483125623050680L;
			@Override
			public void onSubmit() {
				try{
					acaoSalvar();
					setResponsePage(new PaginaListarDiaPraticado(getGrupo()));
					addInfo("Partida cadastrada com sucesso.");
				}catch (NegociosException e) {
					tratarException(e);
				}
			}
		};
		return botao;
	}

	private MenuTopoComponente criarMenuTopo(){
		return new MenuTopoComponente(LIST_MENUS_TOPO_ID, getMenusTopo(), getGrupo().getTipo());
	}

	private ModalWindow criarModal(){
		final ModalWindow modal = new ModalWindow(MODAL_ID);
		List<Usuario> usuarios = getFachada().consultarUsuariosParticipaGrupo(getGrupo());
		modal.setContent(new ModalJogador(modal.getContentId(), usuarios, modal));
		modal.setTitle("Dados Jogador Time");
		modal.setCookieName(MODAL_ID);
		modal.setInitialWidth(500);
		modal.setInitialHeight(250);

		modal.setCloseButtonCallback(new ModalWindow.CloseButtonCallback(){

			private static final long serialVersionUID = 1L;

			@Override
			public boolean onCloseButtonClicked(AjaxRequestTarget target){
				return true;
			}
		});

		modal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback(){

			private static final long serialVersionUID = 1L;

			@Override
			public void onClose(AjaxRequestTarget target){

			}
		});

		return modal;
	}

	private Label criarPlacar(String id, int pontos){
		Label placar = new Label(id, new Model<Integer>(pontos));
		placar.setOutputMarkupId(true);
		return placar;
	}

	private TimeComponent criarTime1(){
		TimeComponent time = new TimeComponent(TIME_1_ID, this, getJogadoresTime1(), TimeComponent.COLOR_RED);
		return time;
	}

	private TimeComponent criarTime2(){
		TimeComponent time = new TimeComponent(TIME_2_ID, this, getJogadoresTime2(), TimeComponent.COLOR_BLUE);
		return time;
	}

	private DropDownChoice<VersusEnum> criarVersus(){
		ChoiceRenderer<VersusEnum> choice = new ChoiceRenderer<VersusEnum>("descricao");
		final DropDownChoice<VersusEnum> drop = new DropDownChoice<VersusEnum>(VERSUS_ID, new PropertyModel<VersusEnum>(this, "versus"), Arrays.asList(VersusEnum.values()), choice);
		drop.add(new AjaxFormSubmitBehavior(JavaScriptParam.ON_CHANGE){

			private static final long serialVersionUID = 5397055010775979989L;

			@Override
			protected void onError(AjaxRequestTarget target) {

			}

			@SuppressWarnings("unchecked")
			@Override
			protected void onSubmit(AjaxRequestTarget target) {
				jogadoresVersus(getJogadoresTime1(), getVersus());
				jogadoresVersus(getJogadoresTime2(), getVersus());

				Form<Component> form = (Form<Component>) getContainer().get(FORM);

				TimeComponent time1 = (TimeComponent) form.get(TIME_1_ID);
				time1.atualizarTime(target);

				TimeComponent time2 = (TimeComponent) form.get(TIME_2_ID);
				time2.atualizarTime(target);
			}

		});
		return drop;
	}

	public DiaPraticadoGrupo getDiaPraticadoGrupo() {
		return diaPraticadoGrupo;
	}

	public List<Jogador> getJogadoresTime1() {
		return jogadoresTime1;
	}

	public List<Jogador> getJogadoresTime2() {
		return jogadoresTime2;
	}

	private List<MenuTopo> getMenusTopo(){
		List<MenuTopo> list = new ArrayList<MenuTopo>();

		Link<Pagina> event1 = new Link<Pagina>(MenuTopoComponente.LINK_MENU_ID) {

			private static final long serialVersionUID = 6408049973489553594L;

			@Override
			public void onClick() {
				try{
					setResponsePage(new PaginaListarDiaPraticado(getGrupo(), getDiaPraticadoGrupo()));
				}catch (ViewException e) {
					redirectViewException(e);
				}
			}
		};
		list.add(new MenuTopo(event1, "Listar Dias Praticado"));

		return list;
	}

	public Partida getPartida() {
		return partida;
	}

	public VersusEnum getVersus() {
		return versus;
	}

	@Override
	public boolean isUpdate() {
		return (getPartida() != null) && (getPartida().getId() != null);
	}

	private List<Jogador> jogadoresVersus(List<Jogador> jogadores, VersusEnum versus){
		int qtd = versus.getValor() - jogadores.size();
		if(qtd > 0){
			for (int i = 0; i < qtd; i++) {
				Jogador jogador = new Jogador();
				jogador.setAdvertencias(new ArrayList<Advertencia>());
				jogadores.add(jogador);
			}
		}else{
			int indexSize = jogadores.size() - 1;
			int length = indexSize - (qtd * -1);
			for (int i = indexSize; i > length; i--) {
				jogadores.remove(i);
			}
		}

		return jogadores;
	}

	@Override
	public void montarPagina() {
		super.montarPagina();
		addContainer(criarMenuTopo());
		Form<Component> form = new Form<Component>(FORM);
		form.add(criarTime1());
		form.add(criarTime2());
		form.add(criarVersus());
		form.add(criarPlacar(PLACAR_VERMELHO, placarTime1));
		form.add(criarPlacar(PLACAR_AZUL, placarTime2));
		form.add(criarBtSalvar());
		addContainer(form);
		addContainer(criarModal());
	}

	private void popularEdicaoJogadores(Partida partida){
		Time time1 = partida.getTimes().get(0);
		setJogadoresTime1(new ArrayList<Jogador>());
		placarTime1 = adicionarJogadoresTime(time1, getJogadoresTime1());

		Time time2 = partida.getTimes().get(1);
		setJogadoresTime2(new ArrayList<Jogador>());
		placarTime2 = adicionarJogadoresTime(time2, getJogadoresTime2());
	}

	@Override
	public void setDefaultModelEntity() {

	}

	public void setDiaPraticadoGrupo(DiaPraticadoGrupo diaPraticadoGrupo) {
		this.diaPraticadoGrupo = diaPraticadoGrupo;
	}

	public void setJogadoresTime1(List<Jogador> jogadoresTime1) {
		this.jogadoresTime1 = jogadoresTime1;
	}


	public void setJogadoresTime2(List<Jogador> jogadoresTime2) {
		this.jogadoresTime2 = jogadoresTime2;
	}

	public void setPartida(Partida partida) {
		this.partida = partida;
	}

	public void setVersus(VersusEnum versus) {
		this.versus = versus;
	}

	@Override
	public boolean viewPublica() {
		return false;
	}

}
